package cn.demo.um.support.factory;

import cn.demo.um.domain.UmAttrData;
import cn.demo.um.service.IUmClientUserService;
import cn.demo.um.support.drive.MatcherDrive;
import cn.demo.um.support.handler.MatcherContext;
import cn.demo.um.support.handler.MatcherHandlerWrapper;
import cn.demo.um.support.model.MatchScoreDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class MatcherDriveFactory {

    @Autowired
    private IUmClientUserService umClientUserService;
    @Autowired
    private MatcherHandlerFactory matcherHandlerFactory;
    @Autowired
    private ISearchAttrIndexFactory searchAttrIndexFactory;

    public MatcherDrive buildMatcherDrive(Collection<UmAttrData> attr, String sex) {
        /*构建出能够作为择偶标准的处理器*/
        Map<String, MatcherHandlerWrapper> matcherHandlerMap = matcherHandlerFactory.getHandlerMap();
        /*初始化每个异性的分数(这里采用懒加载)*/
        Map<String, MatchScoreDto> matchScoreDtoMap =new HashMap<>();
        /**
         * 给用户择偶标准进行分组,使其变成以下格式：age->["18","20"],height->["160","180"]
         */
        Map<String, List<String>> factorMap = attr.stream()
                .collect(Collectors.groupingBy(UmAttrData::getAttrCode, Collectors.mapping(UmAttrData::getAttrValue, Collectors.toList())));
        /*构建上下文，存储择偶参数，和所有异性分数*/
        MatcherContext matcherContext = new MatcherContext(factorMap, matchScoreDtoMap, sex);
        matcherContext.setSearchAttrIndexFactory(searchAttrIndexFactory);
        /*构建出该用户对应择偶标准的所有处理器*/
        List<MatcherHandlerWrapper> matcherHandlerWrappers = factorMap.keySet().stream()
                /*如果数据正确，不需要这条语句*/
                .filter(matcherHandlerMap::containsKey)
                .map(matcherHandlerMap::get)
//                如果有顺序要求的话，可以加上排序
//                .sorted((a, b) -> Math.toIntExact(a.getSort() - b.getSort()))
                .collect(Collectors.toList());
        /*将执行器和上下文封装后返回*/
        return new MatcherDrive(matcherHandlerWrappers, matcherContext);
    }

}
